package com.pikaqiu.warehouse.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.pikaqiu.warehouse.config.MiniConstant;
import com.pikaqiu.warehouse.domain.common.ReqCommonParams;
import com.pikaqiu.warehouse.domain.dto.*;
import com.pikaqiu.warehouse.domain.entity.Category;
import com.pikaqiu.warehouse.domain.entity.MaterialProduct;
import com.pikaqiu.warehouse.domain.entity.Materials;
import com.pikaqiu.warehouse.domain.entity.Products;
import com.pikaqiu.warehouse.domain.req.MaterialForm;
import com.pikaqiu.warehouse.exception.MiniCompanyAuthException;
import com.pikaqiu.warehouse.mapper.MaterialsMapper;
import com.pikaqiu.warehouse.service.*;
import com.pikaqiu.warehouse.utils.StringUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
* @author Administrator
* @description 针对表【materials】的数据库操作Service实现
* @createDate 2024-08-14 14:08:23
*/
@Service
public class MaterialsServiceImpl extends ServiceImpl<MaterialsMapper, Materials>
    implements MaterialsService {

    @Resource
    private UserService userService;

    @Resource
    private CategoryService categoryService;

    @Resource
    private MaterialProductService materialProductService;


    @Resource
    private ProductsService productsService;

    @Override
    public List<Materials> listAllMaterials(Integer companyId) {
        return list(new QueryWrapper<Materials>().eq("company_id", companyId));
    }

    @Override
    public List<CategoryGroupDto> listGroup() {
        ReqCommonParams reqCommonParams = userService.checkUser();;
        List<Materials> list = list(new QueryWrapper<Materials>().eq("company_id", reqCommonParams.getCompanyId()));
        List<Category> productCategoryList = categoryService.listMaterialsCategory(reqCommonParams.getCompanyId());
        List<CategoryGroupContentDto> contentDtoList = list.stream().map(CategoryGroupContentDto::new).collect(Collectors.toList());
        Map<Integer, List<CategoryGroupContentDto>> productMap = contentDtoList.stream()
            .collect(Collectors.groupingBy(CategoryGroupContentDto::getCategory));
        List<CategoryGroupDto> categoryGroupDtoList = new ArrayList<>();
        for (Category category : productCategoryList) {
            List<CategoryGroupContentDto> contentList = productMap.get(category.getId());
            if (CollectionUtil.isEmpty(contentList)) {
                contentList = Collections.emptyList();
            }
            categoryGroupDtoList.add(new CategoryGroupDto(category, contentList));
        }
        return categoryGroupDtoList;
    }

    @Override
    public void saveMaterial(MaterialForm materialForm) {
        ReqCommonParams reqCommonParams = userService.checkUser();;
        Materials materials = materialForm.toMaterials();
        materials.setCompanyId(reqCommonParams.getCompanyId());
        save(materials);
    }

    @Override
    public MaterialProductInfoDto info(Integer id) {
        ReqCommonParams reqCommonParams = userService.checkUser();
        Materials materials = getById(id);
        if (materials == null || !materials.getCompanyId().equals(reqCommonParams.getCompanyId())) {
            throw new MiniCompanyAuthException("公司信息不匹配");
        }
        List<Category> categories = categoryService.listCategory(reqCommonParams.getCompanyId());
        Map<Integer, String> categoryMap = categories.stream().collect(Collectors.toMap(Category::getId, Category::getName));
        List<MaterialProduct> materialProductList = materialProductService.listProductMaterialsByMaterial(materials.getId());
        if (CollectionUtil.isEmpty(materialProductList)) {
            return new MaterialProductInfoDto(materials, categoryMap.get(materials.getCategory()), Collections.emptyList());
        }
        List<Integer> productIdList = materialProductList.stream().map(MaterialProduct::getProductId).collect(Collectors.toList());
        List<Products> productsList = productsService.listByIds(productIdList);
        Map<Integer, Products> productsMap = productsList.stream().collect(Collectors.toMap(Products::getId, Function.identity()));
        List<ProductMaterialsLinkDto> linkList = new ArrayList<>();
        for (MaterialProduct materialProduct : materialProductList) {
            Products products = productsMap.get(materialProduct.getProductId());
            String categoryName = categoryMap.get(materials.getCategory());
            linkList.add(new ProductMaterialsLinkDto(products, categoryName, materialProduct.getQuantity()));
        }
        return new MaterialProductInfoDto(materials, categoryMap.get(materials.getCategory()), linkList);
    }

    @Override
    public MaterialProductLinkInfoDto linkInfo(Integer id) {
        ReqCommonParams reqCommonParams = userService.checkUser();
        Materials materials = getById(id);
        List<MaterialProduct> materialProductList = materialProductService.listProductMaterialsByMaterial(materials.getId());
        Map<Integer, BigDecimal> quantityMap = materialProductList.stream()
            .collect(Collectors.toMap(MaterialProduct::getProductId, MaterialProduct::getQuantity));
        List<Products> productsList = productsService.listAllProduct(reqCommonParams.getCompanyId());
        List<LinkItemDto> linkItemDtoList = productsList.stream().map(LinkItemDto::new).collect(Collectors.toList());
        for (LinkItemDto linkItemDto : linkItemDtoList) {
            BigDecimal quantity = quantityMap.get(linkItemDto.getId());
            if (quantity != null) {
                linkItemDto.setQuantity(quantity);
            } else {
                linkItemDto.setQuantity(BigDecimal.ZERO);
            }
        }
        return new MaterialProductLinkInfoDto(materials, linkItemDtoList);
    }

    @Override
    public void saveLinkInfo(Integer id, String links) {
        List<MaterialProduct> materialProductList = materialProductService.listProductMaterialsByMaterial(id);
        List<String> linkList = StringUtils.split(links, MiniConstant.COMMA);
        Map<Integer, BigDecimal> quantityMap = linkList.stream().map(str -> str.split(MiniConstant.LINE))
            .collect(Collectors.toMap(arr -> Integer.parseInt(arr[0]), arr -> new BigDecimal(arr[1])));
        for (MaterialProduct materialProduct : materialProductList) {
            BigDecimal quantity = quantityMap.get(materialProduct.getProductId());
            if (quantity == null) {
                materialProduct.setQuantity(BigDecimal.ZERO);
            } else {
                materialProduct.setQuantity(quantity);
            }
        }
        // 暂无关联记录
        materialProductList.stream().map(MaterialProduct::getProductId).collect(Collectors.toList())
            .forEach(quantityMap.keySet()::remove);
        List<MaterialProduct> insertList = new ArrayList<>();
        for (Integer productId : quantityMap.keySet()) {
            MaterialProduct materialProduct = new MaterialProduct();
            materialProduct.setProductId(productId);
            materialProduct.setMaterialId(id);
            materialProduct.setQuantity(quantityMap.get(productId));
            insertList.add(materialProduct);
        }
        if (CollectionUtil.isNotEmpty(insertList)) {
            materialProductService.saveBatch(insertList);
        }
        materialProductService.updateBatchById(materialProductList);
    }
}




